package com.ruoyi.system.service.impl;

import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.uuid.IdUtils;
import com.ruoyi.system.domain.SysRefreshToken;
import com.ruoyi.system.mapper.SysRefreshTokenMapper;
import com.ruoyi.system.service.ISysRefreshTokenService;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;

/**
 * Refresh Token Service业务层处理
 *
 * @author ruoyi
 */
@Service
public class SysRefreshTokenServiceImpl implements ISysRefreshTokenService
{
    private static final Logger log = LoggerFactory.getLogger(SysRefreshTokenServiceImpl.class);

    @Autowired
    private SysRefreshTokenMapper sysRefreshTokenMapper;

    /**
     * JWT签名密钥
     */
    @Value("${token.secret}")
    private String secret;

    /**
     * 查询Refresh Token
     *
     * @param id Refresh Token主键
     * @return Refresh Token
     */
    @Override
    public SysRefreshToken selectSysRefreshTokenById(Long id)
    {
        return sysRefreshTokenMapper.selectSysRefreshTokenById(id);
    }

    /**
     * 根据用户ID查询有效的Refresh Token
     *
     * @param userId 用户ID
     * @return Refresh Token
     */
    @Override
    public SysRefreshToken selectByUserId(Long userId)
    {
        return sysRefreshTokenMapper.selectSysRefreshTokenByUserId(userId);
    }

    /**
     * 根据token值查询Refresh Token
     *
     * @param refreshToken token值
     * @return Refresh Token
     */
    @Override
    public SysRefreshToken selectByToken(String refreshToken)
    {
        return sysRefreshTokenMapper.selectSysRefreshTokenByToken(refreshToken);
    }

    /**
     * 查询Refresh Token列表
     *
     * @param sysRefreshToken Refresh Token
     * @return Refresh Token
     */
    @Override
    public List<SysRefreshToken> selectSysRefreshTokenList(SysRefreshToken sysRefreshToken)
    {
        return sysRefreshTokenMapper.selectSysRefreshTokenList(sysRefreshToken);
    }

    /**
     * 新增Refresh Token
     *
     * @param sysRefreshToken Refresh Token
     * @return 结果
     */
    @Override
    public int insertSysRefreshToken(SysRefreshToken sysRefreshToken)
    {
        sysRefreshToken.setCreatedAt(DateUtils.getNowDate());
        return sysRefreshTokenMapper.insertSysRefreshToken(sysRefreshToken);
    }

    /**
     * 修改Refresh Token
     *
     * @param sysRefreshToken Refresh Token
     * @return 结果
     */
    @Override
    public int updateSysRefreshToken(SysRefreshToken sysRefreshToken)
    {
        sysRefreshToken.setUpdatedAt(DateUtils.getNowDate());
        return sysRefreshTokenMapper.updateSysRefreshToken(sysRefreshToken);
    }

    /**
     * 批量删除Refresh Token
     *
     * @param ids 需要删除的Refresh Token主键
     * @return 结果
     */
    @Override
    public int deleteSysRefreshTokenByIds(Long[] ids)
    {
        return sysRefreshTokenMapper.deleteSysRefreshTokenByIds(ids);
    }

    /**
     * 删除Refresh Token信息
     *
     * @param id Refresh Token主键
     * @return 结果
     */
    @Override
    public int deleteSysRefreshTokenById(Long id)
    {
        return sysRefreshTokenMapper.deleteSysRefreshTokenById(id);
    }

    /**
     * 保存或更新用户的Refresh Token
     *
     * @param userId 用户ID
     * @param refreshToken token值
     * @param expiresAt 过期时间
     * @return 结果
     */
    @Override
    public int saveOrUpdateRefreshToken(Long userId, String refreshToken, Date expiresAt)
    {
        log.info("保存或更新用户 {} 的 Refresh Token", userId);
        return sysRefreshTokenMapper.saveOrUpdateRefreshToken(userId, refreshToken, expiresAt);
    }

    /**
     * 使用户的所有Refresh Token失效
     *
     * @param userId 用户ID
     * @return 结果
     */
    @Override
    public int invalidateUserRefreshTokens(Long userId)
    {
        log.info("使用户 {} 的所有 Refresh Token 失效", userId);
        return sysRefreshTokenMapper.invalidateUserRefreshTokens(userId);
    }

    /**
     * 验证Refresh Token是否有效
     *
     * @param userId 用户ID
     * @param refreshToken token值
     * @return 是否有效
     */
    @Override
    public boolean isValidRefreshToken(Long userId, String refreshToken)
    {
        SysRefreshToken token = sysRefreshTokenMapper.validateRefreshToken(userId, refreshToken);
        boolean isValid = token != null;
        log.debug("验证用户 {} 的 Refresh Token: {}", userId, isValid ? "有效" : "无效");
        return isValid;
    }

    /**
     * 清理过期的Refresh Token
     *
     * @return 清理的数量
     */
    @Override
    public int cleanExpiredRefreshTokens()
    {
        int count = sysRefreshTokenMapper.deleteExpiredRefreshTokens();
        if (count > 0)
        {
            log.info("清理过期的 Refresh Token: {} 条", count);
        }
        return count;
    }

    /**
     * 生成Refresh Token
     *
     * @param userId 用户ID
     * @param expireSeconds 过期时间(秒)
     * @return Refresh Token
     */
    @Override
    public String generateRefreshToken(Long userId, long expireSeconds)
    {
        long expireTime = System.currentTimeMillis() + expireSeconds * 1000;

        String refreshToken = Jwts.builder()
                .setSubject(String.valueOf(userId))
                .setId(IdUtils.randomUUID())
                .setIssuedAt(new Date())
                .setExpiration(new Date(expireTime))
                .signWith(SignatureAlgorithm.HS512, secret)
                .compact();

        log.debug("为用户 {} 生成 Refresh Token，过期时间: {} 秒", userId, expireSeconds);
        return refreshToken;
    }
}